package qeug.shsh.facde.controller;

import com.alibaba.fastjson.JSONObject;
import com.drew.lang.annotations.NotNull;
import com.huawei.shade.org.apache.commons.logging.Log;
import com.huawei.shade.org.apache.commons.logging.LogFactory;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
import kd.bos.entity.operate.result.IOperateInfo;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.openapi.common.custom.annotation.*;
import kd.bos.openapi.common.result.CustomApiResult;
import kd.bos.orm.ORM;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.servicehelper.org.OrgUnitServiceHelper;
import kd.bos.servicehelper.org.OrgViewType;
import qeug.shsh.facde.info.BPMApplyModel;
import qeug.shsh.facde.resultext.BPMApplyResultExt;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.*;

@ApiController(value = "BPMApplyController", desc = "通用预算占用单据接口，自定义插件")

public class BPMApplyController {

    private final static Log logger = LogFactory.getLog(BPMApplyController.class);//日志

    @ApiPostMapping(value = "/shsh_bpmapply", desc = "通用申请api接口")
    public CustomApiResult<@ApiResponseBody("返回参数") BPMApplyResultExt> BPMApply
            (@NotNull @Valid @ApiRequestBody(value = "入参") BPMApplyModel model) {

        logger.info("费用申请接到入参日志" + JSONObject.toJSONString(model));
        CustomApiResult applyResultExt = new CustomApiResult();

        String requestId = model.getRequestId();//事前申请流程id
        String applierName = model.getApplierName();//申请人名称
        String applierNum = model.getApplierNum();//申请人编号
        String companyName = model.getCompanyName();//申请人公司名称
        String companyNumber = model.getCompanyNumber();//申请人公司编号
        String adminOrgName = model.getAdminOrgName();//申请人部门名称
        String adminOrgNumber = model.getAdminOrgNumber();//申请人部门编号
        Date bizDate = model.getBizDate();//申请日期
        String costDeptName = model.getCostDeptName();//费用承担部门名称
        String costDeptNumber = model.getCostDeptNumber();//费用承担部门编号
        Boolean isCurrency = model.getCurrency();//多币种
        String description = model.getDescription();//事由

        QFilter[] f1 = new QFilter[]{new QFilter("billno", QCP.equals, requestId)};
        DynamicObject dailyApply = BusinessDataServiceHelper.loadSingle("er_dailyapplybill", f1);//查询是否存在事前申请单据
        if (dailyApply == null) {
            ORM orm = ORM.create();
            dailyApply = orm.newDynamicObject("er_dailyapplybill");//创建事前申请单
        }
        DynamicObject applier = getEntity(applierNum, "bos_user");//申请人
        if (applier == null) {
            applyResultExt.setStatus(false);
            applyResultExt.setMessage("申请人不存在");
            applyResultExt.setErrorCode("400");//状态码
            return applyResultExt;
        }
        QFilter qFilter = new QFilter("toorg.number", "=", adminOrgNumber);//申请人部门
        QFilter[] qFilters = new QFilter[]{qFilter};
        DynamicObject orgrelation = BusinessDataServiceHelper.loadSingle("bos_org_orgrelation_dept", qFilters);//业务单元分配部门
        if (orgrelation == null) {
            applyResultExt.setStatus(false);
            applyResultExt.setMessage("部门未在业务单元分配部门表中维护");
            applyResultExt.setErrorCode("400");//状态码
            return applyResultExt;
        } else {
            DynamicObject fromorg = orgrelation.getDynamicObject("fromorg");
            dailyApply.set("costcompany", fromorg);//费用承担公司
        }
        DynamicObject adminOrg = getEntity(adminOrgNumber, "bos_adminorg");
        if (adminOrg == null) {
            applyResultExt.setStatus(false);
            applyResultExt.setMessage("未在行政组织中查询到对应的部门信息");
            applyResultExt.setErrorCode("400");//状态码
            return applyResultExt;
        } else {
            dailyApply.set("org", adminOrg);
        }
        DynamicObject costDept = getEntity(costDeptNumber, "bos_adminorg");
        if (costDept != null) {
            //一级承担部门赋值逻辑：查找费用承担部门的最上级部门
            DynamicObject orgPattern = costDept.getDynamicObject("orgpattern");//形态
            if (orgPattern != null) {
                String orgPatternNumber = orgPattern.getString("number");
                if (!orgPatternNumber.equals("Orgform06")) {
                    //填写的费用承担部门的形态不是部门时，直接将费用承担部门值赋值给一级承担部门
                    dailyApply.set("qeug_costdept", costDept);//一级承担部门
                } else {
                    // 当费用承担部门形态为部门时，需要查找其最上级部门
                    DynamicObject currentOrg = costDept;
                    DynamicObject topLevelDept = null;

                    // 循环查找最上级部门
                    while (true) {
                        long currentOrgId = Long.parseLong(currentOrg.getString("id"));
                        Map<Long, Long> orgParentMap = OrgUnitServiceHelper.getDirectSuperiorOrg(OrgViewType.Admin, Collections.singletonList(currentOrgId));

                        Long parentId = orgParentMap.get(currentOrgId);
                        if (parentId == null) {
                            // 没有上级组织，当前组织就是最顶级组织
                            topLevelDept = currentOrg;
                            break;
                        }

                        DynamicObject parentOrg = BusinessDataServiceHelper.loadSingle("bos_adminorg",
                                new QFilter[]{new QFilter("id", QCP.equals, parentId)});

                        if (parentOrg != null) {
                            DynamicObject parentOrgPattern = parentOrg.getDynamicObject("orgpattern");
                            if (parentOrgPattern != null) {
                                String parentOrgPatternNumber = parentOrgPattern.getString("number");
                                if (!parentOrgPatternNumber.equals("Orgform06")) {
                                    // 上级组织不是部门类型，当前组织即为一级承担部门
                                    topLevelDept = currentOrg;
                                    break;
                                }
                            }
                            // 继续向上查找
                            currentOrg = parentOrg;
                        } else {
                            // 无法加载上级组织，当前组织为最顶级
                            topLevelDept = currentOrg;
                            break;
                        }
                    }

                    dailyApply.set("qeug_costdept", topLevelDept);//一级承担部门
                }
            }
        }
        dailyApply.set("costdept", costDept);
        dailyApply.set("bizdate", bizDate);
        dailyApply.set("iscurrency", false);
        dailyApply.set("description", description);
        DynamicObject com = getEntity("60000000", "bos_adminorg");
        dailyApply.set("company", com); //默认板块
        dailyApply.set("qeug_processinstance", requestId);//事前申请流程id
        dailyApply.set("billno", requestId);//单据编码
        dailyApply.set("applier", applier);//申请人
        dailyApply.set("creator", applier);//创建人
        dailyApply.set("tel", applier.getString("phone"));//联系方式
        dailyApply.set("applierpositionstr", applier.getDynamicObjectCollection("entryentity").get(0).getString("position"));//职位文本

        //默认携带固定值
        dailyApply.set("billstatus", "C");//单据状态默认为提交
        QFilter[] f2 = new QFilter[]{
                new QFilter("number", QCP.equals, "er_dailyapplybill_BT")};
        DynamicObject document_type = BusinessDataServiceHelper.loadSingle("bos_billtype", f2);
        dailyApply.set("qeug_document_type", document_type);//单据类型（默认为通用费用申请单)
        dailyApply.set("currency", BusinessDataServiceHelper.loadSingle("bd_currency", new QFilter[]{
                new QFilter("number", QCP.equals, "CNY")}));//本位币别(默认为人民币)
        dailyApply.set("formid", "er_dailyapplybill");//表单id(默认费用申请单)
        dailyApply.set("reimbursetype", "expense");//申请类型(默认费用报账)

        List<BPMApplyModel.FyEntry> fyEntry = model.getFyEntry();//费用明细
        BigDecimal totalApp = BigDecimal.ZERO;
        if (fyEntry != null) {
            DynamicObjectCollection expenseCollection = dailyApply.getDynamicObjectCollection("expenseentryentity");//费用明细
            expenseCollection.clear();
            DynamicObjectType expenseType1 = expenseCollection.getDynamicObjectType();
            for (int k = 0; k < fyEntry.size(); k++) {
                BPMApplyModel.FyEntry entry = fyEntry.get(k);
                DynamicObject expenseEntry = new DynamicObject(expenseType1);
//                String expenseType = entry.getExpenseType();//费用类型
//                String expenseDetail = entry.getExpenseDetail(); // 费用细项
                String expenseItemName = entry.getExpenseItemName(); // 费用名目名称
                String expenseItemNumber = entry.getExpenseItemNumber(); // 费用名目编码
                Date happenDate = entry.getHappendate(); // 费用发生日期
                String entryCurrency = entry.getEntryCurrency(); // 币别
                int exchangeRate = entry.getExchanGerate(); // 汇率
                BigDecimal exchangeRateBD = new BigDecimal(exchangeRate);
                BigDecimal amount = entry.getAmount(); // 申请金额
                BigDecimal amountRaw = entry.getAmountRaw(); // 申请金额（本位币）
                String comment = entry.getComment(); // 备注

//                QFilter f2 = new QFilter("fullname", "=", expenseItemName);
                QFilter f3 = new QFilter("number", "=", expenseItemNumber);
                QFilter[] f4 = new QFilter[]{f3};
                DynamicObject expense = BusinessDataServiceHelper.loadSingle("er_expenseitemedit", f4);
                expenseEntry.set("expenseitem", expense);
                if (expense != null) {
                    DynamicObject expenseDetail = expense.getDynamicObject("parent");//费用细项
                    expenseEntry.set("qeug_expensedetail", expenseDetail);
                    DynamicObject expenseType = expenseDetail.getDynamicObject("parent");//费用类型
                    expenseEntry.set("qeug_expensetype", expenseType);
                }
                expenseEntry.set("happendate", happenDate);
                QFilter[] f7 = new QFilter[]{
                        new QFilter("number", QCP.equals, entryCurrency)};
                DynamicObject currency = BusinessDataServiceHelper.loadSingle("bd_currency", f7);
                expenseEntry.set("entrycurrency", currency);
                expenseEntry.set("exchangerate", exchangeRate);
                expenseEntry.set("expenseamount", amount);
                expenseEntry.set("currexpenseamount", amountRaw);
                expenseEntry.set("expeapproveamount", amount);//核定金额
                if (amount != null) {
                    expenseEntry.set("expeapprovecurramount", amount.multiply(exchangeRateBD));//核定金额本位币：等于汇率乘申请金额
                    totalApp = totalApp.add(amount);
                }
                expenseEntry.set("qeug_notes", comment);

                expenseEntry.set("seq", k + 1);
                expenseEntry.set("expquotetype", "0");//换算方式(默认直接汇率)

                expenseCollection.add(expenseEntry);
            }
        }
        dailyApply.set("applyamount", totalApp);//申请金额
        dailyApply.set("approveamount", totalApp);//核定金额
        dailyApply.set("billcanloanamount", totalApp);//可借金额
        dailyApply.set("approveamount", totalApp);//核定金额
        //BPM调用接口传入JSON至费控，生成通用事前申请
        OperateOption saveOption = OperateOption.create();
        saveOption.setVariableValue("ignoreValidation", String.valueOf(true));//绕过网络互斥操作
        SaveServiceHelper.saveOperate("er_dailyapplybill", new DynamicObject[]{dailyApply}, OperateOption.create());
        OperationResult operationResult = SaveServiceHelper.saveOperate("audit", "er_dailyapplybill", new DynamicObject[]{dailyApply}, saveOption);//调用审核操作
        boolean success = operationResult.isSuccess();
        if (success) {
            applyResultExt.setStatus(true);
            applyResultExt.setMessage("调用成功");//输出成功消息
            applyResultExt.setErrorCode("200");//状态码
        } else {
            applyResultExt.setStatus(false);//是否成功
            String message = operationResult.getMessage();
            for (IOperateInfo errInfo : operationResult.getAllErrorOrValidateInfo()) {
                message = errInfo.getMessage();
            }
            applyResultExt.setMessage("调用失败,失败原因：" + message);//输出失败原因
            logger.info("费用申请保存失败:" + message);
            applyResultExt.setErrorCode("400");//状态码
        }
//        applyResultExt.setTimestamp(new Date());//调用时间
//        CustomApiResult<@ApiResponseBody("返回参数") BPMApplyResultExt> success1 = CustomApiResult.success(applyResultExt);
        return applyResultExt;
    }

    public static DynamicObject getEntity(String number, String entityName) {
        QFilter f1 = new QFilter("number", "=", number);
        QFilter[] f3 = new QFilter[]{f1};
        return BusinessDataServiceHelper.loadSingle(entityName, f3);
    }
}
